package com.leimo.util;

import java.util.List;
import java.util.Map;
import java.util.Set;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

/**
 * redis操作工具类 使用redis做列队，采用redis中list的push和pop操作 结合列队的特点： 只允许在一端插入新元素只能在队列的尾部FIFO:先进先出原则
 * Redis中lpush头入(rpop尾出)或rpush尾入(lpop头出)可以满足要求, 而Redis中list药push或　pop的对象仅需要转换成byte[]即可
 * java采用Jedis进行Redis的存储和Redis的连接池设置 参考博客：https://www.cnblogs.com/kinglf/p/5972300.html
 *
 * @author 夏智峰
 * @create 2018-02-07 15:41
 */
public class RedisUtils {
  private static String JEDIS_IP = "127.0.0.1";
  private static int JEDIS_PORT = 9455;
  private static String JEDIS_PASSWORD = null;
  private static JedisPool jedisPool;

  static {
    JedisPoolConfig config = new JedisPoolConfig();
    config.setMaxIdle(256);
    config.setMaxWaitMillis(5000L);
    config.setTestOnBorrow(true);
    config.setTestOnReturn(true);
    config.setTestWhileIdle(true);
    config.setMinEvictableIdleTimeMillis(60000L);
    config.setTimeBetweenEvictionRunsMillis(3000L);
    config.setNumTestsPerEvictionRun(-1);
    jedisPool = new JedisPool(config, JEDIS_IP, JEDIS_PORT, 60000);
  }

  /**
   * 获取数据
   */
  public static String get(String key) {
    String value = null;
    Jedis jedis = null;
    try {
      jedis = jedisPool.getResource();
      value = jedis.get(key);
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      //Jedis3.0后，returnResource就不使用了，建议用close替换。
      //即：jedisPool.returnResource(jedis) ---> jedis.close();
      jedis.close();
    }
    return value;
  }

  public static byte[] get(byte[] key) {
    byte[] value = null;
    Jedis jedis = null;
    try {
      jedis = jedisPool.getResource();
      value = jedis.get(key);
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      jedis.close();
    }
    return value;
  }

  public static byte[] hget(byte[] key, byte[] field) {
    byte[] value = null;
    Jedis jedis = null;
    try {
      jedis = jedisPool.getResource();
      value = jedis.hget(key, field);
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      jedis.close();
    }
    return value;
  }

  public static String hget(String key, String field) {
    String value = null;
    Jedis jedis = null;
    try {
      jedis = jedisPool.getResource();
      value = jedis.hget(key, field);
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      jedis.close();
    }
    return value;
  }

  /**
   * 存储数据
   */
  public static void set(byte[] key, byte[] value) {
    Jedis jedis = null;
    try {
      jedis = jedisPool.getResource();
      jedis.set(key, value);
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      jedis.close();
    }
  }

  public static void set(byte[] key, byte[] value, int timeOut) {
    Jedis jedis = null;
    try {
      jedis = jedisPool.getResource();
      jedis.set(key, value);
      //过期时间秒
      jedis.expire(key, timeOut);
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      jedis.close();
    }
  }

  public static void hset(byte[] key, byte[] field, byte[] value) {
    Jedis jedis = null;
    try {
      jedis = jedisPool.getResource();
      jedis.hset(key, field, value);
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      jedis.close();
    }
  }

  public static void hset(String key, String field, String value) {
    Jedis jedis = null;
    try {
      jedis = jedisPool.getResource();
      jedis.hset(key, field, value);
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      jedis.close();
    }
  }

  /**
   * 删除数据
   */
  public static void del(byte[] key) {
    Jedis jedis = null;
    try {
      jedis = jedisPool.getResource();
      jedis.del(key);
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      jedis.close();
    }
  }

  public static void del(String key) {
    Jedis jedis = null;
    try {
      jedis = jedisPool.getResource();
      jedis.del(key);
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      jedis.close();
    }
  }

  public static void hdel(byte[] key, byte[] field) {
    Jedis jedis = null;
    try {
      jedis = jedisPool.getResource();
      jedis.hdel(key, field);
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      jedis.close();
    }
  }

  public static void hdel(String key, String field) {
    Jedis jedis = null;
    try {
      jedis = jedisPool.getResource();
      jedis.hdel(key, field);
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      jedis.close();
    }
  }

  /**
   * 存储redis队列 顺序存储
   */
  public static void lpush(byte[] key, byte[] value) {
    Jedis jedis = null;
    try {
      jedis = jedisPool.getResource();
      jedis.lpush(key, value);
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      jedis.close();
    }
  }

  /**
   * 存储redis队列 反向存储
   */
  public static void rpush(byte[] key, byte[] value) {
    Jedis jedis = null;
    try {
      jedis = jedisPool.getResource();
      jedis.rpush(key, value);
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      jedis.close();
    }
  }

  /**
   * 将列表source中的最后一个元素（尾元素）弹出，并返回给客户端
   * @param key redis 键名
   * @param destination 键值
   */
  public static void rpoplpush(byte[] key, byte[] destination) {
    Jedis jedis = null;
    try {
      jedis = jedisPool.getResource();
      jedis.rpoplpush(key, destination);
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      jedis.close();
    }
  }

  /**
   * 获取队列数据
   */
  public static List<byte[]> lpopList(byte[] key) {
    List<byte[]> list = null;
    Jedis jedis = null;
    try {
      jedis = jedisPool.getResource();
      list = jedis.lrange(key, 0, -1);
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      jedis.close();
    }
    return list;
  }

  /**
   * 获取列队数据
   */
  public static byte[] rpop(byte[] key) {
    byte[] value = null;
    Jedis jedis = null;
    try {
      jedis = jedisPool.getResource();
      value = jedis.rpop(key);
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      jedis.close();
    }
    return value;
  }

  /**
   * 将相应的字段设置为相应的值。 HMSET用新值替换旧值。
   * 如果密钥不存在，则创建一个保存散列的新密钥。
   * @param key
   * @param hash
   */
  public static void hmset(Object key, Map hash) {
    Jedis jedis = null;
    try {
      jedis = jedisPool.getResource();
      jedis.hmset(key.toString(), hash);
    } catch (Exception e) {
      e.printStackTrace();

    } finally {
      jedis.close();
    }
  }


  /**
   * 将相应的字段设置为相应的值。 HMSET用新值替换旧值。
   * 如果密钥不存在，则创建一个保存散列的新密钥。
   * @param key
   * @param hash
   * @param time
   */
  public static void hmset(Object key, Map hash, int time) {
    Jedis jedis = null;
    try {

      jedis = jedisPool.getResource();
      jedis.hmset(key.toString(), hash);
      jedis.expire(key.toString(), time);
    } catch (Exception e) {
      e.printStackTrace();

    } finally {
      jedis.close();

    }
  }

  /**
   * 获取与指定字段关联的值
   * @param key
   * @param fields
   * @return
   */
  public static List<String> hmget(Object key, String... fields) {
    List<String> result = null;
    Jedis jedis = null;
    try {

      jedis = jedisPool.getResource();
      result = jedis.hmget(key.toString(), fields);

    } catch (Exception e) {
      e.printStackTrace();

    } finally {
      jedis.close();

    }
    return result;
  }

  /**
   * 返回hash的所有字段
   * @param key
   * @return
   */
  public static Set hkeys(String key) {
    Set result = null;
    Jedis jedis = null;
    try {
      jedis = jedisPool.getResource();
      result = jedis.hkeys(key);

    } catch (Exception e) {
      e.printStackTrace();

    } finally {
      jedis.close();

    }
    return result;
  }

  /**
   * 返回存储在指定键上的列表的指定元素。开始和结束基于零的索引。
   * 0是列表的第一个元素（列表头），1是下一个元素和
   */
  public static List<byte[]> lrange(byte[] key, int from, int to) {
    List<byte[]> result = null;
    Jedis jedis = null;
    try {
      jedis = jedisPool.getResource();
      result = jedis.lrange(key, from, to);

    } catch (Exception e) {
      e.printStackTrace();

    } finally {
      jedis.close();

    }
    return result;
  }

  /**
   * 获取key中的所有hash
   * @param key
   * @return
   */
  public static Map<byte[], byte[]> hgetAll(byte[] key) {
    Map<byte[], byte[]> result = null;
    Jedis jedis = null;
    try {
      jedis = jedisPool.getResource();
      result = jedis.hgetAll(key);
    } catch (Exception e) {
      e.printStackTrace();

    } finally {
      jedis.close();
    }
    return result;
  }

  /**
   * 存储在指定键上的列表的长度
   * @param key
   * @return
   */
  public static long llen(byte[] key) {

    long len = 0;
    Jedis jedis = null;
    try {
      jedis = jedisPool.getResource();
      jedis.llen(key);
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      jedis.close();
    }
    return len;
  }
}
